package org.space.galaxyCabinet.factory.impl;

import org.space.galaxyCabinet.annotation.GuiguEmqx;
import org.space.galaxyCabinet.factory.MessageHandlerFactory;
import org.space.galaxyCabinet.handler.MassageHandler;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;


@Service
public class MessageHandlerFactoryImpl implements MessageHandlerFactory, ApplicationContextAware {


    private Map<String, MassageHandler> handlerMap = new HashMap<>();

    /**
     * 初始化bean对象
     *
     * @param ioc
     */
    @Override
    public void setApplicationContext(ApplicationContext ioc) {
        // 获取对象
        Map<String, MassageHandler> beanMap = ioc.getBeansOfType(MassageHandler.class);
        for (MassageHandler massageHandler : beanMap.values()) {
            GuiguEmqx guiguEmqx = AnnotatedElementUtils.findAllMergedAnnotations(massageHandler.getClass(), GuiguEmqx.class).iterator().next();
            if (null != guiguEmqx) {
                String topic = guiguEmqx.topic();
                // 初始化到map
                System.out.println("初始化主题："+topic);
                handlerMap.put(topic, massageHandler);
            }
        }
    }

    @Override
    public MassageHandler getMassageHandler(String topic) {
        if (handlerMap.get(topic) != null) {
            return handlerMap.get(topic);
        } else {
            for (String key : handlerMap.keySet()) {
                String pattern = key;
                pattern = pattern
                        .replace("+", "[^/]+")
                        .replace("#", ".*")
                        .replace("$", "\\$");
                pattern = "^"+pattern+"$";
                if (Pattern.matches(pattern, topic)) {
                    return handlerMap.get(key);
                }
            }
        }
        return null;
    }
}
